Semantik Web  •  Hafta 10

SWRL API & SQWRL

Kuralları Java'dan çalıştırmak, SQWRL ile sorgulamak ve alerji sisteminin uçtan uca tamamlanması

Lisansüstü Semantik Web Dersi  •  CMPE 583

Hafta 10  •  Kazanımlar

Bu hafta sonunda

  • SWRL API ile kural motorunu Java'dan çalıştırabileceksiniz.
  • Kuralları kodla oluşturup ontolojiye ekleyebileceksiniz.
  • SQWRL sorgularıyla çıkarım sonuçlarını raporlayabileceksiniz.
  • Protégé SWRLTab / SQWRLTab akışını doğru sırayla uygulayabileceksiniz.
  • Reasoner ile kural motorunun iş bölümünü açıklayabileceksiniz.

01

SWRL Nedir?

Tanım, konum ve API'ye neden ihtiyaç var.

SWRL: Semantic Web Rule Language

OWL DL'in tanımlama mantığı ile RuleML'in Horn kurallarını birleştiren, W3C'ye sunulmuş bir kural dilidir.

Ne yapar

Var olan bilgiden yeni bilgi türetir.

Nerede durur

OWL'un üstünde, sorgu katmanının altında.

Projede

S1–S7: risk zinciri ve BMI hesabı.

Neden SWRL API gerekli?

İhtiyaçProtégé SWRLTabSWRL API
Kuralı bir kez çalıştırmakYeterYeter
Her istekte çalıştırmakİnsan gerekirOtomatik
Web servisine bağlamakMümkün değilDoğal
Kuralı kodla üretmekElle yazılırProgramatik
Sonucu JSON'a çevirmekYokKolay
Birim testiYokJUnit

Protégé kuralı tasarlamak, SWRL API kuralı işletmek içindir.

Üç bileşeni ayırt edin

SWRLAPI

Kuralı okur, yazar, motora taşır. Ontoloji tarafı.

Drools

Gerçek kural motoru. İleri zincirleme yapar.

SQWRL

Kural sonuçlarını sorgular. Ontolojiyi değiştirmez.

Üçü tek Maven bağımlılığıyla gelir: swrlapi-drools-engine.

Reasoner ile kural motoru farkı

BoyutHermiT / PelletDrools (SWRL)
Ne yaparSınıflandırır, denetlerKural gövdesi eşleşirse baş yazar
AritmetikYokVar
Sonuç kalıcı mıBellekte (geçici)Ontolojiye yazılabilir
Tutarsızlık bulur muEvetHayır
ProjedeADIM 3 ve 7 denetimADIM 5 çıkarım

İkisi birbirinin yerine geçmez: HermiT sınıflandırır, Drools hesaplar ve zincirler.

02

SWRL API Kullanımı

Küçük küçük örneklerle, satır satır.

Adım 0 — Tek bağımlılık

<dependency> <groupId>edu.stanford.swrl</groupId> <artifactId> swrlapi-drools-engine </artifactId> <version>2.1.2</version> </dependency>
  • Drools'u kendisi getirir — ayrıca eklemeyin.
  • OWL API 4.x dalını bekler.
  • Java 8 ile en güvenli çalışır.

Adım 1 — Motoru kur ve çalıştır

SWRLRuleEngine engine = SWRLAPIFactory.createSWRLRuleEngine(ont); engine.infer();
  • createSWRLRuleEngine ontolojiyi alır, kuralları bulur, Drools'a taşır.
  • infer() üç işi birlikte yapar: aktar, çalıştır, sonucu ontolojiye yaz.
  • Protégé'deki üç düğmenin (OWL+SWRL → Drools, Run, Drools → OWL) tek satırlık karşılığıdır.

Adım 2 — Kuralları listele

SWRLRuleEngine engine = SWRLAPIFactory.createSWRLRuleEngine(ont); for (SWRLAPIRule r : engine.getSWRLRules()) System.out.println(r.getRuleName() + " : " + r.getComment());
S1_FishRisk : Sodium Ascorbate balik riski S4_BMI : Kilo ve boydan BMI S6_GenericAllergen : Genel risk zinciri S7_RiskClass : Riskli kisi sinifi

Kural adı burada işe yarar: hangi kuralın yüklendiğini çalıştırmadan önce görürsünüz.

Adım 3 — Önce ve sonra ölç

int before = ont.getAxiomCount(); engine.infer(); int after = ont.getAxiomCount(); System.out.println("Kural cikti: " + (after - before) + " aksiyom");
Kural cikti: 14 aksiyom

Bu iki satır, en değerli hata ayıklama aracınızdır: 0 görüyorsanız literal tipi ya da namespace hatası vardır.

Adım 4 — Çıkarılan bilgiyi oku

engine.infer(); EntitySearcher.getObjectPropertyValues( ind("TC_001"), op("Effected_Allergen"), ont) .forEach(v -> System.out.println("Suclu katki: " + v));
Suclu katki: Nisin

infer() sonucu asserted yazdığı için normal EntitySearcher ile okunur; reasoner gerekmez.

Adım 5 — Hesaplanan değeri oku

EntitySearcher.getDataPropertyValues(ind("TC_004"), dp("hasBMI"), ont) .forEach(l -> System.out.printf("BMI = %.2f%n", l.parseDouble()));
BMI = 33.43

parseDouble() literalin tipini denetler; string gelirse istisna atar — sessiz hatayı görünür yapar.

Adım 6 — Kuralın yazdığı sınıf üyeliği

EntitySearcher.getIndividuals(cls("PersonAtRisk"), ont) .forEach(i -> System.out.println(i.getIRI().getShortForm()));
TC_001 TC_002 TC_003 TC_004

Kural öncesi bu liste boştu. Dört kişinin de riskli çıkması, S6 + S7 zincirinin çalıştığının kanıtıdır.

Adım 7 — Kuralı metin olarak ekle

SWRLRuleEngine engine = SWRLAPIFactory.createSWRLRuleEngine(ont); engine.createSWRLRule("S8_Obese", "Person(?p) ^ hasBMI(?p, ?b) " + "^ swrlb:greaterThanOrEqual(?b, 30.0) -> ObesePerson(?p)"); engine.infer();

En pratik yol: kuralı Protégé sözdizimiyle yazarsınız, API ayrıştırır. Hafta 07'de gördüğümüz SWRLRule nesnesi kurmaya gerek kalmaz.

Adım 8 — Hatayı yakala

try { engine.createSWRLRule("S9", "Person(?p) ^ hasAge(?p, ?a) " + "^ swrlb:greaterThan(?a, \"18\") -> Adult(?p)"); // esik metin! engine.infer(); } catch (SWRLParseException | SWRLRuleEngineException e) { System.err.println("Kural hatasi: " + e.getMessage()); }
Kural hatasi: incompatible argument types for swrlb:greaterThan (xsd:int, xsd:string)

Doğrusu — eşik tipli sayı olarak yazılır

"Person(?p) ^ hasAge(?p, ?a) ^ swrlb:greaterThan(?a, 18) -> Adult(?p)"

Adım 9 — Çıkarımı kalıcı yap

engine.infer(); man.saveOntology(ont, new RDFXMLDocumentFormat(), IRI.create(new File("ALLERGY_INFERRED.owl").toURI()));

Artık dosyada Effected_Allergen, hasBMI ve PersonAtRisk bildirimleri yazılı durur. Bu dosya Protégé'de açıldığında kural motoru olmadan da riskleri gösterir.

03

SQWRL ile Sorgulama

Kural gövdesi + select: rapor üretmenin en kısa yolu.

SQWRL: Semantic Query-Enhanced Web Rule Language

  • SWRL kuralının başını bir sorgu operatörüyle değiştirir.
  • Ontolojiyi değiştirmez — sadece tablo döndürür.
  • Gövde sözdizimi SWRL ile birebir aynıdır.
# SWRL — yazar Person(?p) ^ hasAge(?p,?a) ^ swrlb:greaterThan(?a,18) -> Adult(?p)
# SQWRL — sorar Person(?p) ^ hasAge(?p,?a) ^ swrlb:greaterThan(?a,18) -> sqwrl:select(?p, ?a)

Q1 — Kişi başına BMI

Person(?p) ^ hasName(?p, ?n) ^ hasBMI(?p, ?b) -> sqwrl:select(?n, ?b)
Ayse 23.92 FATMA 28.26 MEHMET 26.60 AYNUR 33.43

Bu sorgu ancak infer() sonrası sonuç verir — hasBMI S4 kuralının ürünüdür.

Q2 — Riskli seçimler ve suçlu katkı

Person(?p) ^ hasName(?p, ?n) ^ ChooseProduct(?p, ?u) ^ Effected_Allergen(?p, ?f) -> sqwrl:select(?n, ?u, ?f)
Ayse EAN_00004 Nisin FATMA EAN_00003 Casein MEHMET EAN_00003 Casein MEHMET EAN_00003 Sodium_Ascorbite AYNUR EAN_00002 Soy_Lecitin

MEHMET iki satırda görünür: iki alerjisi iki farklı katkıdan tetikleniyor.

Q3 — Sırala, say, sınırla

Person(?p) ^ hasName(?p, ?n) ^ hasBMI(?p, ?b) -> sqwrl:select(?n, ?b) ^ sqwrl:orderByDescending(?b) ^ sqwrl:limit(2)
AYNUR 33.43 FATMA 28.26
# katki sayisi Product(?u) ^ Contain(?u, ?f) -> sqwrl:count(?f)

SQWRL operatörleri

Operatörİşi
sqwrl:selectSütun seçer
sqwrl:selectDistinctTekrarları atar
sqwrl:count / sum / avg / min / maxToplulaştırma
sqwrl:orderBy / orderByDescendingSıralama
sqwrl:limitSatır sınırı
sqwrl:columnNamesSütun başlığı
sqwrl:makeSet / difference / intersectionKüme işlemleri

Küme farkı: "riskli olmayan kişiler"

Person(?p) ^ sqwrl:makeSet(?all, ?p) ^ PersonAtRisk(?r) ^ sqwrl:makeSet(?risky, ?r) ^ sqwrl:difference(?safe, ?all, ?risky) -> sqwrl:select(?safe)

Hafta 07'de SWRL ile yazamadığımız olumsuzlama, SQWRL'de küme farkıyla çözülür. Sorgu düzeyinde kapalı dünya varsayımı yapılabilir; kural düzeyinde yapılamaz.

Java — SQWRL sorgusu çalıştır

SQWRLQueryEngine q = SWRLAPIFactory.createSQWRLQueryEngine(ont); SQWRLResult res = q.runSQWRLQuery("Q1", "Person(?p) ^ hasName(?p, ?n) ^ hasBMI(?p, ?b) " + "-> sqwrl:select(?n, ?b)"); while (res.next()) System.out.printf("%-8s %.2f%n", res.getValue("n").getLiteral(), res.getValue("b").asLiteralResult().getDouble());

Sorgu adı ("Q1") zorunludur; sonuçlar bu adla önbelleğe alınır.

SQWRLResult: satır ve sütun

MetotDöndürdüğü
next()Sonraki satıra geçer (JDBC gibi)
getNumberOfRows()Satır sayısı
getValue("n")Değişken adıyla hücre
asLiteralResult()Literal olarak yorum
getNamedIndividual("p")Birey olarak yorum

Yanlış tip metodunu çağırmak istisna atar — bu iyidir, sessiz hata olmaz.

Java — sorgudan rapor üret

List<Map<String,String>> rows = new ArrayList<>(); SQWRLResult r = q.runSQWRLQuery("Q2", RISK_QUERY); while (r.next()) { Map<String,String> row = new LinkedHashMap<>(); row.put("kisi", r.getValue("n").getLiteral()); row.put("urun", r.getValue("u").toString()); row.put("katki", r.getValue("f").toString()); rows.add(row); }

Bu liste doğrudan JSON'a çevrilerek Hafta 06'daki REST uç noktasından döndürülür — sistem böylece tamamlanır.

04

Protégé Arayüzünde

SWRLTab ve SQWRLTab ekran ekran.

Protégé ekranı: SWRLTab

EntitiesSWRLTabSQWRLTab
NameRule
S6_GenericAllergenPerson(?p) ^ hasAllergy(?p,?al) ^ … → Effected_Allergen(?p,?f)
S7_RiskClassPerson(?p) ^ Effected_Allergen(?p,?f) → PersonAtRisk(?p)
1 · OWL+SWRL → Drools 2 · Run Drools 3 · Drools → OWL

Şematik gösterim. Bu üç düğme, Java'da tek infer() çağrısıdır.

Protégé ekranı: motor günlüğü

SWRLTab  ›  Drools Rule Engine  ›  Console
Transferred 118 OWL axioms and 7 SWRL rules to rule engine Ran rule engine. Inferred 14 axioms (812 ms) Transferred 14 inferred axioms to OWL model

Üç satır, üç düğmeye karşılık gelir. Üçüncü satır yoksa ontoloji değişmemiştir — sınıfta en sık atlanan adım budur.

Protégé ekranı: SQWRLTab

SWRLTabSQWRLTab
Person(?p) ^ hasName(?p, ?n) ^ hasBMI(?p, ?b) -> sqwrl:select(?n, ?b) ^ sqwrl:orderByDescending(?b)
nb AYNUR33.43 FATMA28.26 MEHMET26.60
RunSave as CSV

Şematik gösterim. Sorgu ontolojiyi değiştirmediği için istediğiniz kadar deneyebilirsiniz.

Protégé ekranı: kural sonrası TC_001

Individuals by class  ›  Person  ›  TC_001
Types Person Adult  ·  PersonAtRisk   (S5, S7) Property assertions Effected_Allergen  Nisin   (S6) hasBMI  23.92   (S4)

Sarı satırlar kural motorunun yazdıklarıdır ve dosyada kalıcıdır — reasoner çıkarımından farkı budur.

05

Avantajlar ve Tam Akış

Sekiz adımda uçtan uca çalışan sistem.

SWRL API'nin avantajları

  • Tek satırla çıkarım: infer() üç adımı birleştirir.
  • Kalıcı sonuç: çıktı asserted yazılır, sıradan API ile okunur.
  • Metinden kural: Protégé sözdizimi doğrudan ayrıştırılır.
  • Aritmetik: reasoner'ın yapamadığını yapar.
  • Sorgu bütünleşik: SQWRL aynı gövdeyi kullanır, yeni dil öğrenilmez.
  • Otomasyon: servis, zamanlanmış iş, test.
  • İzlenebilirlik: hangi kural hangi aksiyomu yazdı — raporlanabilir.
  • Taşınabilirlik: Protégé'de tasarla, üretimde çalıştır.

Sınırları da bilin

SınırSonucuNe yapmalı
Olumsuzlama yok"Yok" bilgisi yazılamazSQWRL küme farkı
DL-safe kısıtAnonim bireyler görülmezBireyleri adlandır
Literal tipi sessiz hataBoş sonuçAksiyom farkını ölç
Bellek içi çalışmaÇok büyük veride yavaşParçalı işle
Sürüm hassasiyetiNoSuchMethodErrorTek OWL API dalı

Main.java — sekiz adımlı akış

AdımİşAraç
1Ontolojiyi yükleOWL API
2Envanteri yazdırOWL API
3Kural öncesi denetimHermiT
4Kuralları listeleSWRL API
5infer() — kuralları çalıştırDrools
6SQWRL sorgularıSQWRL
7Kural sonrası denetimHermiT
8ALLERGY_INFERRED.owl kaydetOWL API

Akışın çekirdeği: on satır

OWLOntology ont = man.loadOntologyFromOntologyDocument(owlFile); OWLReasoner hermit = new ReasonerFactory().createReasoner(ont); System.out.println("Tutarli mi? " + hermit.isConsistent()); SWRLRuleEngine engine = SWRLAPIFactory.createSWRLRuleEngine(ont); engine.infer(); SQWRLQueryEngine q = SWRLAPIFactory.createSQWRLQueryEngine(ont); printResult(q.runSQWRLQuery("Q2", RISK_QUERY)); man.saveOntology(ont, new RDFXMLDocumentFormat(), inferredIRI);

Dönem sonu çıktısı

ADIM 3 — HermiT ON Denetim Tutarli mi? true PersonAtRisk uyeleri (BOS beklenir): [] ADIM 5 — SWRLRuleEngine.infer() 14 aksiyom yazildi (812 ms) ADIM 6 — SQWRL Q1 Ayse 23.92 FATMA 28.26 MEHMET 26.60 AYNUR 33.43 Q2 Ayse EAN_00004 Nisin | MEHMET EAN_00003 Casein ADIM 7 — HermiT SON Denetim PersonAtRisk : [TC_001, TC_002, TC_003, TC_004] Adult : [TC_001, TC_003, TC_004]

06

Final Projesi

Uçtan uca çalışan sistemin teslimi.

Final projesi — teslim

  1. Ontoloji: en az 8 sınıf, 12 özellik, 40 birey.
  2. En az 8 SWRL kuralı; biri aritmetik, biri zincir.
  3. 3 SQWRL sorgusu; biri toplulaştırma, biri küme işlemi.
  4. Sekiz adımlı Java uygulaması.
  5. Kural öncesi/sonrası karşılaştırma raporu.

Dosyalar

ontology.owl ontology_inferred.owl maven-project/ rapor.pdf (8-10 sayfa) sunum.pdf (10 dakika)

Final değerlendirme ölçütleri

ÖlçütAğırlıkBeklenen
Ontoloji tasarımı20%Kısıtlar gerekçeli, tutarlı
Kural tabanı25%Çeşitli, güvenli, test edilmiş
SQWRL raporlama15%Toplulaştırma ve küme işlemi
Java uygulaması25%Sekiz adım çalışıyor
Rapor ve sunum15%Kararlar savunulmuş

Kaynaklar

  • W3C — SWRL: A Semantic Web Rule Language Combining OWL and RuleML, 2004.
  • O'Connor, M., Das, A. — SQWRL: A Query Language for OWL, OWLED 2009.
  • SWRLAPI belgeleri ve wiki — github.com/protegeproject/swrlapi.
  • O'Connor, M. et al. — Supporting Rule System Interoperability on the Semantic Web with SWRL, ISWC 2005.
  • Drools belgeleri — ileri zincirleme ve çakışma çözümü.

Özet  •  1 / 2

SWRL API

  • SWRL = OWL DL + Horn kuralları; RDFS/OWL'un yapamadığını yapar.
  • infer() Protégé'nin üç düğmesine eşdeğerdir.
  • Kural çıktısı asserted yazılır; sıradan API ile okunur, dosyada kalır.
  • Kuralı metin olarak eklemek en pratik yoldur.
  • Aksiyom farkını ölçmek en hızlı hata ayıklama yöntemidir.

Özet  •  2 / 2

SQWRL ve dönem kapanışı

  • SQWRL kural gövdesini kullanır; başında sorgu operatörü vardır.
  • Ontolojiyi değiştirmez — güvenle denenir.
  • Küme farkı, SWRL'de olmayan olumsuzlamayı sağlar.
  • Sekiz adım: yükle → denetle → çalıştır → sorgula → kaydet.

On hafta sonunda

Bir gıda etiketinden başlayıp, çıkarım yapan ve gerekçesini gösteren çalışan bir semantik sistem kurdunuz.

IRI → XML → RDF → RDFS → OWL → OWL-S → SWRL → API → Reasoner → SQWRL

Tekrar Soruları

Kendinizi sınayın

  1. infer() hangi üç işi yapar?
  2. Kural çıktısı ile reasoner çıkarımı arasındaki fark nedir?
  3. SQWRL neden ontolojiyi değiştirmez?
  4. Aksiyom farkı 0 ise nereye bakarsınız?
  1. Küme farkı hangi sorunu çözer?
  2. Q1 sorgusu neden infer() öncesi boş döner?
  3. Drools → OWL adımı atlanırsa ne olur?
  4. HermiT ve Drools'un iş bölümü nedir?

Alıştırma  •  Sınıf içi

Sorguyu siz yazın

"Her ürünün kaç alerjen katkı içerdiğini, çoktan aza sıralı" bir SQWRL sorgusu yazın.

Product(?u) ^ Contain(?u, ?f) ^ ______(?f, ?al) -> sqwrl:______(?u) ^ sqwrl:______(?u)

Sorular

  1. Hangi ürün başa gelir?
  2. Ascorbic_Acid sayılır mı? Neden?
  3. Bu sorgu infer() öncesi çalışır mı?